package main

import (
	"fmt"
	"math"
	"reflect"
	"runtime"
)

/**
	返回值类型写在最后面
	可返回多个值
	函数作为参数
	没有默认参数，可选参数，只有可变参数列表
 */

func eval(a, b int, op string) (int, error)  {
	switch op {
	case "+":
		return a + b, nil
	case "-":
		return a - b, nil
	case "*":
		return a * b, nil
	case "/":
		if b == 0 {
			return 0, fmt.Errorf("b is not 0")
		}
		return a / b, nil
	default:
		//panic("unsupported operation: " + op)	//中断执行
		return 0, fmt.Errorf("unsupported operation: " + op) //error输出,返回
	}
}

//多返回值，一般返回err
func div(a, b int) (int, int) {
	return a / b, a % b
}

func main()  {
	fmt.Print(eval(1,5,"+"))
	r, b := div(5,2)
	q, _ := div(7,3)
	fmt.Print(r,b)
	fmt.Print(q)
	res, err := eval(3, 9, "+")
	if err != nil {
		 fmt.Print(err)
	}
	fmt.Print(res)
	fmt.Println(apply(pow,3,4))

	//可变参数
	fmt.Print(sum(1,2,3,4,5))
}

//函数型编程
//函数参数
func apply(op func(int,int) int, a, b int) int {
	p := reflect.ValueOf(op).Pointer()
	opName := runtime.FuncForPC(p).Name()
	fmt.Printf("calling function %s with args " + "(%d, %d) \n", opName, a, b)
	return  op(a,b)
}

func pow(a, b int) int {
	return int(math.Pow(float64(a), float64(b)))
}


//可变参数列表
func sum(numbers ...int) int {
	s := 0
	for i := range numbers {
		s += numbers[i]
	}
	return s
}


